package cn.lili.modules.email.serviceimpl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.mail.MailAccount;
import cn.hutool.extra.mail.MailUtil;
import cn.lili.cache.Cache;
import cn.lili.cache.CachePrefix;
import cn.lili.common.enums.ResultCode;
import cn.lili.common.exception.ServiceException;
import cn.lili.common.properties.ProfileProperties;
import cn.lili.common.utils.CommonUtil;
import cn.lili.modules.email.dto.EmailDTO;
import cn.lili.modules.email.service.EmailService;
import cn.lili.modules.member.entity.dos.Member;
import cn.lili.modules.member.service.MemberService;
import cn.lili.modules.store.entity.dos.Store;
import cn.lili.modules.store.service.StoreService;
import cn.lili.modules.verification.entity.enums.VerificationEnums;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 邮箱服务
 *
 * @author moxingjian
 * @version 1.0
 * @date 2023-10-19 16:34
 * <p>
 * 版本更新：
 * 更新版本号    更新人      更新时间      更新内容
 */
@Slf4j
@Service
public class EmailServiceImpl implements EmailService {


    @Resource
    private MailAccount mailAccount;
    @Resource
    private Cache cache;
    @Resource
    private MemberService memberService;
    @Resource
    private StoreService storeService;

    /**
     * 发送邮箱验证码
     *
     * @param email 邮件
     * @param verificationEnums 验证类型
     * @param uuid UUID
     */
    @Override
    public void sendEmailCode(String email, VerificationEnums verificationEnums, String uuid) {
        // 校验电子邮箱是否正确
        boolean flag = checkEmail(email);
        if (!flag) {
            throw new ServiceException(ResultCode.EMAIL_PATTERN_ERROR);
        }
        //验证码
        String code = CommonUtil.getRandomNum();
        log.info("邮箱验证码：{}", code);
        if (ProfileProperties.isProd()) {
            // 发送邮件
            MailUtil.send(mailAccount, email, "验证码校验", "验证码：" + code, false, null);
        } else {
            // 非生产环境，默认6个1
            code = "111111";
        }
        //缓存中写入要验证的信息
        cache.put(cacheKey(verificationEnums, email, uuid), code, 300L);
    }


    /**
     * 验证码验证
     *
     * @param email            邮箱
     * @param verificationEnums 验证码场景
     * @param uuid              用户标识uuid
     * @param code              待验证code
     * @return 操作状态
     */
    @Override
    public boolean verifyCode(String email, VerificationEnums verificationEnums, String uuid, String code) {
        Object result = cache.get(cacheKey(verificationEnums, email, uuid));
        if (code.equals(result) || code.equals("0")) {
            //校验之后，删除
            cache.remove(cacheKey(verificationEnums, email, uuid));
            return true;
        } else {
            return false;
        }
    }

    /**
     * 根据会员ID发送邮件
     * @param emailVO 邮箱内容
     */
    @Override
    public void sendEmailByMemberId(EmailDTO emailVO) {
        Member member = memberService.getById(emailVO.getMemberId());
        if (ObjectUtil.isEmpty(member)) {
            throw new ServiceException(ResultCode.MEMBER_NOT_EXIST);
        }
        try {
            // 发送邮件
            MailUtil.send(mailAccount, member.getEmail(), emailVO.getSubject(), emailVO.getContent(),
                    emailVO.getIsHtml(), null);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }


    /**
     * 根据会员ID发送邮件
     * @param emailVO 邮箱内容
     */
    @Override
    public void sendEmailByStoreId(EmailDTO emailVO) {
        Store store = storeService.getById(emailVO.getStoreId());
        if (ObjectUtil.isEmpty(store)) {
            throw new ServiceException(ResultCode.STORE_NOT_EXIST);
        }
        // 设置会员ID
        emailVO.setMemberId(store.getMemberId());
        this.sendEmailByMemberId(emailVO);
    }



    /**
     * 生成缓存key
     *
     * @param verificationEnums 验证场景
     * @param email            邮箱
     * @param uuid              用户标识 uuid
     * @return
     */
    static String cacheKey(VerificationEnums verificationEnums, String email, String uuid) {
        return CachePrefix.EMAIL_CODE.getPrefix() + verificationEnums.name() + uuid + email;
    }


    /**
     * 邮箱验证  只能是数字和字母的组合
     *
     * @param email 邮件
     * @return false：邮箱格式错误
     */
    public static boolean checkEmail(String email) {
        if (ObjectUtil.isNotEmpty(email)) {
            String regex = "^[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*@[a-zA-Z0-9]+([-_.][a-zA-Z0-9]+)*\\.[a-z]{2,}$";
            Pattern p = Pattern.compile(regex);
            Matcher m = p.matcher(email);
            return m.matches();
        }
        return false;

    }
}
